package com.nbicc.dp.modular.aspectj;

import com.nbicc.core.utils.ExceptionUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by li on 17/12/25.
 * 日志拦截aop
 */
@Slf4j
@Aspect
@Component
@Order(1)
public class LogAspect {

    @Value("${spring.profiles.active}")
    private String springProfile;

    @Pointcut("execution(* com.nbicc..*.*Controller.*(..))")
    public void executeService(){
    }

    @Before("executeService()")
    public void doBefore(JoinPoint joinPoint){

        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes =(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 记录下请求内容
        log.info("请求开始=====================================================================================");
        log.info("URL : " + request.getRequestURL().toString());
        log.info("HTTP_METHOD : " + request.getMethod());
        log.info("IP : " + request.getRemoteAddr());
        log.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName()+ "." + joinPoint.getSignature().getName());
        log.debug("ARGS : " + Arrays.toString(joinPoint.getArgs()));

        //只有在开发或者测试环境的时候  记录request中的参数
        if(!StringUtils.isEmpty(springProfile)){
            if("dev".equals(springProfile) || "test".equals(springProfile)){
                //debug 获取所有参数：
                Map<String,Object> e = new HashMap<String, Object>();
                Enumeration<String> enu=request.getParameterNames();
                while(enu.hasMoreElements()){
                    String paraName= enu.nextElement();
                    e.put(paraName,request.getParameter(paraName));
                }
                log.debug("REQUEST PARAMETER: " + e.toString());
            }
        }
    }

    @Around(value = "executeService()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
        //计算方法执行时间
        long startTime = System.currentTimeMillis();
        Object proceed = joinPoint.proceed();
        log.info("return : "+proceed);
        log.info(joinPoint.getSignature().getDeclaringTypeName()+ "." + joinPoint.getSignature().getName()
                +" SPEND TIME : " + (System.currentTimeMillis() - startTime)+ "ms");
        return proceed;
    }

    @AfterThrowing(value = "executeService()" , throwing="e")
    public void doBefore(JoinPoint joinPoint , Exception e){
        log.error(ExceptionUtil.getStackTraceInfo(e));
        log.info("错误请求结束====================================================================================");
    }

    @AfterReturning("executeService()")
    public void doAfterReturning(JoinPoint joinPoint){
        log.info("请求结束====================================================================================");
    }

}
